﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Asol.Reporting.Support
{
    #region interface IDataSource : deklarace pluginu který tvoří zdroj dat (definice reportu, definice selectu, načítání dat reportu)
    /// <summary>
    /// Předpis pro třídy, které mohou být datovým zdrojem.
    /// Úkolem datového zdroje je zprostředkování přenosu dat mezi konkrétním informačním systémem a report enginem.
    /// Datový zdroj tedy dokáže získat a vrátit definici celého reportu, který bude editován/generován (definice ve formě frx.xml nebo pbl.srd).
    /// Dále dokáže editovat datový zdroj oblasti reportu (SQL dotaz, strom tříd, atd), který je následně ukládán ve formě stringu do reportu.
    /// Poté dokáže pro danou definici datového zdroje získat reálná data do reportu a vrátit je ve formě tabulky, odkud je report engine zobrazuje.
    /// Tabulka může být vybavena (na úrovni sloupce nebo buňky) informací o formátovacím stylu (editační maska, editační styl, položky pro konverzi dat na texty).
    /// </summary>
    public interface IDataSource : IPlugin
    {
        /// <summary>
        /// Priorita zdroje: vyšší hodnota vyhrává (pokud není zdroj určen explicitně parametrem Source=Namespace.TypeName)
        /// </summary>
        int Priority { get; }
        /// <summary>
        /// Metoda je volána pro provedení funkční inicializace zdroje dat.
        /// Je volaná v době první potřeby tohoto zdroje, v inicializovaném prostředí.
        /// </summary>
        void Initialize();
        /// <summary>
        /// Nabídne uživateli okno s výběrem reportů pro editaci.
        /// Jak bude okno vypadat a odkud bude uživatel vybírat reporty, to je věcí konkrétního zdroje.
        /// Výstupem je identifikátor reportu, který bude následně načten metodou LoadReportDefinition().
        /// Pokud uživatel nic nevybere, výstupem je null a nic se nebude editovat.
        /// Identifikátorem může být číslo, název, cokoliv. 
        /// ReportEngine to nepotřebuje, jen to otestuje na not null a předá do LoadReportDefinition().
        /// Pokud datový zdroj nemá v úmyslu povolovat interaktivní editaci, bez dialogu vrátí null.
        /// </summary>
        /// <returns></returns>
        object SelectReportForEditing();
        /// <summary>
        /// Načte a vrátí definici reportu z informačního systému.
        /// Definice má být primárně ve formátu FRX.XML (pak je do OUT parametru format uložena konstanta DataSource.FORMAT_FRX_XML).
        /// Definice může být načtena i ve formátu SRD (format = konstanta DataSource.FORMAT_PBL_SRD).
        /// Může být i v dalších formátech, které jsou uvedeny v konstantách DataSource.FORMAT_*, 
        /// tyto formáty dokáže report engine interně konvertovat.
        /// Identifikátor reportu je předán jako object, konkrétní typ je dán informačním systémem.
        /// ID reportu buď volí spouštěcí mechanismus tvorby reportu, anebo jej vrátila metoda SelectReportForEditing() tohoto datového zdroje.
        /// </summary>
        /// <param name="reportId"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        string LoadReportDefinition(object reportId, out string format);
        /// <summary>
        /// Uloží definici reportu. Report mohl být načten a modifikován, pak má svoje ID určené, 
        /// anebo byl vytvořen jako nový, a pak je jako reportId předáno null.
        /// Při ukládání se pro report musí vytvořit konkrétní ID (typicky nový klíč v databázi), a tento klíč se vepíše do ref parametru reportId.
        /// Report engine si jej přiřadí k reportu, a následné ukládání se bude provádět již pro toto nově přidělené ID.
        /// Obsah definice je v této metodě vždy již FRX.XML, report engine neukládá jiný formát 
        /// (jiné formáty dokáže jen importovat, ale ne do nich exportovat, nemusí dovolovat uložení všech atributů nového reportu).
        /// </summary>
        /// <param name="definition"></param>
        /// <param name="reportId"></param>
        /// <returns></returns>
        bool SaveReportDefinition(string definition, ref object reportId);
        /// <summary>
        /// Metoda dostává definici zdroje dat tak, jak ji sama posledně při editaci uložila.
        /// Nabídne uživateli okno se zadáním datového zdroje (SQL SELECT, nebo strom tříd, nebo cokoliv podle uvážení).
        /// Uživate může data editovat, změní hodnoty parametrů source a parameters, a uloží je = vrátí hodnotu true.
        /// Pokud uživatel změny neuloží, pak vrátí false, a report engine bude ignorovat hodnotu v ref parametru source i parameters.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        bool EditDataSource(ref string source, ref string parameters);
        /// <summary>
        /// Datový zdroj získá konkrétní hodnoty parametrů reportu.
        /// Předpis parametrů (string parameters) si vytvořil tentýž datový zdroj v metodě EditDataSource().
        /// Na základě tohoto předpisu datový zdroj do dodané tabulky vepíše řádky, kde jeden řádek odpovídá jedné hodnotě parametru.
        /// Může si vyžádat interakci od uživatele (zobrazit okno parametrů).
        /// Tabulka pro naplnění parametrů je připravena enginem (obsahuje potřebné sloupce).
        /// Metoda do tabulky přidává řádky odpovídající předpisu parametrů (názvy, hodnoty).
        /// Metoda vrací true, když jsou data připravena a report se má vytvářet;
        /// nebo vrací false když uživatel okno parametrů stornoval a report se vytvářet nemá.
        /// </summary>
        /// <param name="parameters"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        bool FillReportParameters(string parameters, Data.Table table);
        /// <summary>
        /// Datový zdroj získá data do vlastního reportu.
        /// Zdroj dat (SQL dotaz, nebo strom tříd, nebo cokoliv dalšího) je předáno jako parametr stringový source.
        /// Definici tohoto zdroje dat si vytvořil tentýž datový zdroj v metodě EditDataSource().
        /// Parametry jsou předány ve formě tabulky. Obsah tabulky si vytvořil datový zdroj sám v metodě GetReportParameters().
        /// </summary>
        /// <param name="source"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        Data.Table LoadReportData(string source, Data.Table parameters);
        /// <summary>
        /// Metoda zajistí formátování dat načtených v tabulce (výstup metody LoadReportData()) podle formátovacího předpisu (format), uvedeného v reportu, 
        /// do textové podoby, která bude vytisknuta v reportu.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="formatName"></param>
        /// <returns></returns>
        string FormatValueToText(Data.ValueData value, string formatName);
        /// <summary>
        /// Metoda zajistí formátování hodnoty od uživatele do hodnoty pro uložení dat do tabulky.
        /// </summary>
        /// <param name="text">Hodnota od uživatele (nejčastěji string)</param>
        /// <param name="formatName">Název formátu, může být null</param>
        /// <param name="targetType">Cílový typ dat ukládaných do tabulky (načteno ze sloupce)</param>
        /// <returns></returns>
        Data.ValueData FormatTextToValue(object text, string formatName, Data.ValueDataType targetType);
        /// <summary>
        /// Metoda vrátí formátovací styl daného jména.
        /// Používá se typicky pro získání položek editačního stylu pro ComboBox.
        /// </summary>
        /// <param name="formatName">Název formátu, může být null</param>
        /// <returns></returns>
        FormatStyle GetFormatStyle(string formatName);
    }
    #endregion
}
